local g_files = {};

function makedirs(root)
    local index = 0;
    while index
    do
        index = string.find(root, '/', index+1);
        if index then
            CCFile:makedir(string.sub(root, 1, index));
        end
    end
end

function _removeDir(root)
    if CCFile:isFile(root) then CCFile:removeFile(root)
    elseif CCFile:isDir(root) then CCFile:removeDir(root) end;
end;
function removeDir(root)
    traverse(root, nil, _removeDir);
end

function _add_search_path(root)
    if CCFile:isDir(root) then CCFileUtils:sharedFileUtils():addSearchPath(root) end;
end;
function add_search_path()        
    CCFileUtils:sharedFileUtils():removeAllPaths();
    traverse(get_writable_path().."data", _add_search_path);
    traverse("data", _add_search_path);
end;

function traverse(root, pre, post)
    if type(pre)=="function" then
        pre(root);
    end

    local files=CCFile();
    local f=files:openDir(root);
    while f and f~=""
    do
        if not string.find(f, "[.]$") then
            traverse(f, pre, post);
        end
        f=files:readDir();
    end
     
    if type(post)=="function" then
        post(root);
    end
end

function hash_file(root)
    
    print(root);
end

function start_update(url)
    CCFile:makedir(get_writable_path());

    add_search_path();
    
    local reader = GUIReader:shareReader();
    local ccsLayout = nil;
    if reader then 
        ccsLayout = reader:widgetFromJsonFile("load.json") 
    end;
    
    require "rsc"
    require "scene"
    local scene = CCScene:create();
    --scene:addChild(load_ccbi("loading.ccbi"));
    scene:addChild(ccsLayout);
    run_scene(scene)
    
    if 1 then return end;
    
    _G.url = string.match(url, "http[s]?://[^/]+/");
    _G.download_succ = 0;
    _G.download_fail = 0;
    _G.download_total = 0;
    download(url);
end

function get_writable_path()
    local path=CCFileUtils:sharedFileUtils():getWritablePath();
    return path..(string.find(path, '[/]$') and '' or '/').."OK/";
end

function download(url)
    if url then
        local ccupdate = CCUpdate:create();
        print("download.."..url);
        ccupdate:setUrl(url)
        ccupdate:setRequestType(CCHttpRequest.kHttpPost)   
        ccupdate:setCallBack(download_complete) 
        CCHttpClient:getInstance():send(ccupdate)   
        ccupdate:release();
    end
end

function file_size(path)
    local file = io.open(path, "rb");
    if not file then return -1 end;
    return file:seek("end");
end

function file_md5(path)
    return "";
end

function is_same_file(path, size, md5)
    return size==file_size(path) and md5==file_md5(path);
end

function end_update()
    add_search_path();
    package.loaded["rsc"] = nil
    package.loaded["scene"] = nil
    require "start"
    start_run();
end

function download_complete(request, response, data, header)
    if not response:isSucceed() or not data then 
        _G.download_fail = _G.download_fail + 1;
        if 0==_G.download_total or _G.download_fail+_G.download_succ==_G.download_total then end_update() end;
        print("error code="..response:getResponseCode());
        return 
    end;

    print(_G.download_succ.."/".._G.download_total..",".."url="..request:getUrl());
    --print("tag="..request:getTag());
    --print("code="..response:getResponseCode());
    --print("error="..response:getErrorBuffer());
    --print("data="..data);

    if 0 == _G.download_total then
        v = loadstring(data)();
        for i in pairs(v) 
        do
            if type(v[i]) == "table" then
                if v[i]["url"] and v[i]["path"] and v[i]["size"] and v[i]["md5"] then 
                    local path=v[i]["path"];
                    local writable_path = get_writable_path()..path;
                    if (CCFile:isFile(writable_path) and not is_same_file(writable_path, v[i]["size"], v[i]["md5"])) 
                        or (not CCFile:isFile(writable_path) and not is_same_file(path, v[i]["size"], v[i]["md5"])) then
                        g_files[_G.url..v[i]["url"]] = v[i];
                        _G.download_total = _G.download_total + 1;
                    end
                end
            end
        end
        for i in pairs(v)
        do
            download(_G.url..v[i]["url"]);
        end          
    else
        _G.download_succ = _G.download_succ + 1;
        local f = g_files[request:getUrl()];
        if f then
            local path = get_writable_path()..f["path"];
            if CCFile:isDir(path) then removeDir(path) end;
            local dir = string.match(path, "(.+/)[^/]*");
            if dir and dir~=path and not CCFile:isFile(dir) and not CCFile:isDir(dir) then 
                makedirs(dir);
            end             
            local out = io.open(path, "wb");
            if out then 
                out:write(data)
                out:close()
            else print("io.open failed") end;
        end
    end
    
    if _G.download_fail+_G.download_succ==_G.download_total then
        end_update();
    end
end



